package com.powernode.driver.service.impl;

import com.powernode.common.execption.PowerException;
import com.powernode.common.result.ResultCodeEnum;
import com.powernode.driver.config.TencentProperties;
import com.powernode.driver.service.CiService;
import com.powernode.driver.service.CosService;
import com.powernode.model.vo.driver.CosUploadVo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.GeneratePresignedUrlRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.StorageClass;
import com.qcloud.cos.region.Region;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class CosServiceImpl implements CosService {
    @Resource
    private TencentProperties tencentProperties;
    @Resource
    private CiService ciService;

    /**
     * <p>上传文件</p>
     * <p>1. 文件重命名</p>
     * <p>2. 上传文件到cos中</p>
     * <p>3. 获取上传文件的url</p>
     * <p>4. 构建vo对象返回</p>
     *
     * @param file 上传的文件
     * @param path 自己指定的上传文件夹
     */
    @SneakyThrows
    @Override
    public CosUploadVo upload(MultipartFile file, String path) {
        COSClient cosClient = cosClient();
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(file.getSize());
        objectMetadata.setContentType(file.getContentType());
        objectMetadata.setContentEncoding("UTF-8");
        // 获取后缀名
        String fileType = Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf("."));
        String uploadPath = "/driver" + path + "/" + UUID.randomUUID().toString().replaceAll("-", "") + fileType;
        try {
            // 构建上传请求对象
            PutObjectRequest putObjectRequest = new PutObjectRequest(tencentProperties.getBucketPrivate(), uploadPath, file.getInputStream(), objectMetadata);
            putObjectRequest.setStorageClass(StorageClass.Standard);
            // 上传文件
            cosClient.putObject(putObjectRequest);
            cosClient.shutdown();
            // 审核图片
            Boolean isAuditing = ciService.imageAuditing(uploadPath);
            if (!isAuditing) {
                // 删除违规图片
                cosClient.deleteObject(tencentProperties.getBucketPrivate(), uploadPath);
                throw new PowerException(ResultCodeEnum.IMAGE_AUDITION_FAIL);
            }
            CosUploadVo cosUploadVo = new CosUploadVo();
            cosUploadVo.setUrl(uploadPath);
            cosUploadVo.setShowUrl(getImageUrl(uploadPath));
            return cosUploadVo;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取上传文件的显示
     */
    @Override
    public String getImageUrl(String uploadPath) {
        COSClient cosClient = cosClient();
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(tencentProperties.getBucketPrivate(), uploadPath, HttpMethodName.GET);
        Date date = new DateTime().plusMinutes(20).toDate();
        generatePresignedUrlRequest.setExpiration(date);
        URL url = cosClient.generatePresignedUrl(generatePresignedUrlRequest);
        cosClient.shutdown();
        return url.toString();
    }


    private COSClient cosClient() {
        COSCredentials cred = new BasicCOSCredentials(tencentProperties.getSecretId(),
                tencentProperties.getSecretKey());
        Region region = new Region(tencentProperties.getRegion());
        ClientConfig clientConfig = new ClientConfig(region);
        clientConfig.setHttpProtocol(HttpProtocol.https);
        return new COSClient(cred, clientConfig);
    }
}